﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using AppToolkit.WPF.UI.Converters;
using System.Windows;

namespace AppToolkit.WPF.Tests.UI.Converters
{
    [TestFixture]
    public class BoolToVisiblityConverterTests
    {
        BoolToVisiblityConverter _target;

        [SetUp]
        public void Setup()
        {
            _target = new BoolToVisiblityConverter();
        }

        #region Convert Tests
        [Test,Sequential]
        public void Forward_conversion(
            [ValueSource(typeof(ForwardConvertionData), "Inputs")] object value,
            [ValueSource(typeof(ForwardConvertionData), "Expectation")] object expectedValue)
        {
            var res = _target.Convert(value, typeof(Visibility), null, null);
            Assert.AreEqual(expectedValue, res);
        }

        [Test, Sequential]
        public void Forward_conversion_with_parameter_true_for_inversion(
            [ValueSource(typeof(ForwardConvertionData), "Inputs")] object value,
            [ValueSource(typeof(ForwardConvertionData), "InvertedExpectation")] object expectedValue)
        {
            _target.InvertLogic = true;
            var res = _target.Convert(value, typeof(Visibility), null, null);
            Assert.AreEqual(expectedValue, res);
        }

        [Test, Sequential]
        public void Forward_conversion_with_HiddenMapping_override(
            [ValueSource(typeof(ForwardConvertionData), "Inputs")] object value,
            [ValueSource(typeof(ForwardConvertionData), "OverrideExpectation")] object expectedValue)
        {
            _target.HiddenValue = Visibility.Hidden;
            var res = _target.Convert(value, typeof(Visibility), false, null);
            Assert.AreEqual(expectedValue, res);
        }
        #endregion

        #region HiddenMapping Tests
        [Test]
        public void HiddenMapping_default_is_Collapsed()
        {
            Assert.AreEqual(Visibility.Collapsed, _target.HiddenValue);
        }

        [Test, ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void HiddenMapping_checks_for_valid_input()
        {
            _target.HiddenValue = Visibility.Visible;
        }
        #endregion

        #region ConvertBack Tests
        [Test, Sequential]
        public void Backward_conversion(
            [ValueSource(typeof(BackwardConvertionData), "Inputs")] object value,
            [ValueSource(typeof(BackwardConvertionData), "Expectation")] object expectedValue)
        {
            var res = _target.ConvertBack(value, typeof(bool), null, null);
            Assert.AreEqual(expectedValue, res);
        }

        [Test, Sequential]
        public void Backward_conversion_with_inversion(
            [ValueSource(typeof(BackwardConvertionData), "Inputs")] object value,
            [ValueSource(typeof(BackwardConvertionData), "InvertedExpectation")] object expectedValue)
        {
            _target.InvertLogic = true;
            var res = _target.ConvertBack(value, typeof(bool), true, null);
            Assert.AreEqual(expectedValue, res);
        }
        #endregion

        #region Internals
        class ForwardConvertionData
        {
            object[] Inputs = new object[]
            {
                null,4321,false,true
            };

            object[] Expectation = new object[]
            {
                DependencyProperty.UnsetValue, DependencyProperty.UnsetValue,Visibility.Collapsed,Visibility.Visible
            };

            object[] InvertedExpectation = new object[]
            {
                DependencyProperty.UnsetValue, DependencyProperty.UnsetValue,Visibility.Visible,Visibility.Collapsed
            };

            object[] OverrideExpectation = new object[]
            {
                DependencyProperty.UnsetValue, DependencyProperty.UnsetValue,Visibility.Hidden,Visibility.Visible
            };
        }

        class BackwardConvertionData
        {
            object[] Inputs = new object[]
            {
                null,4321,Visibility.Visible,Visibility.Collapsed,Visibility.Hidden
            };

            object[] Expectation = new object[]
            {
                DependencyProperty.UnsetValue, DependencyProperty.UnsetValue,true,false,false
            };

            object[] InvertedExpectation = new object[]
            {
                DependencyProperty.UnsetValue, DependencyProperty.UnsetValue,false,true,true
            };

            //object[] InvertedExpectation = new object[]
            //{
            //    DependencyProperty.UnsetValue, DependencyProperty.UnsetValue,Visibility.Visible,Visibility.Collapsed
            //};

            //object[] OverrideExpectation = new object[]
            //{
            //    DependencyProperty.UnsetValue, DependencyProperty.UnsetValue,Visibility.Hidden,Visibility.Visible
            //};
        }
        #endregion
    }
}
